package org.wattdepot.cli.command;

import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.cli.processor.CommandLineInterface;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Calculates the total amount of carbon or energy generated by a source.
 * 
 * @author Kendyll Doi
 * @author Kimberly Heu
 *
 */
public class WattTotalGenerated {
  
  /**
   * Calculates either the total carbon or total energy generated by a source over a given day,
   * sampling a given number of minutes.
   * 
   * @param property What to find the total of (carbon or energy).
   * @param source The source to get the information about.
   * @param day The day to get the information about.
   * @param minutes The number of minutes between samples.
   * @param client The WattDepot client
   * @return A string containing either the total carbon or total energy generated.
   */
  public static String totalGenerated(String property, String source, String day, String minutes, 
      WattDepotClient client) {
    // Messages to be displayed in the case of an error
    String resourceNotFoundMessage = "No data found for ";
    String miscClientMessage = "Error while retrieving resource";
    String notAuthorizedMessage = "Not authorized to retrieve information.";
    String badXmlMessage = "Error enountered getting information from server.";
    String numberFormatMessage = "Incorrect input for minutes value.";
    
    String out = ""; // Output string
    StringBuffer buf = new StringBuffer(500); // Buffer to collect output
    
    XMLGregorianCalendar startTime; // Time to begin sample
    XMLGregorianCalendar endTime; // Time to end sample
    int interval; // The interval between samplings
    
    try {
      // Initialize the start and end times
      
      // Try to create a timestamp. If it is invalid, the method will return null
      // so return the appropriate error message.
      startTime = CommandLineInterface.createTstamp(day);
      if (startTime == null) {
        return ("Incorrect timestamp input.");
      }
      
      endTime = Tstamp.incrementDays(startTime, 1);
      
      // Parse the interval
      interval = Integer.parseInt(minutes);
      
      if (property.equalsIgnoreCase("carbon")) {
        // If the property is carbon, get the carbon emitted
        buf.append("Carbon generated: ");
        buf.append(client.getCarbonEmitted(source, startTime, endTime, interval));
      }
      else if (property.equalsIgnoreCase("energy")) {
        // If the property is energy, get the energy generated
        buf.append("Energy generated: ");
        buf.append(client.getEnergyGenerated(source, startTime, endTime, interval));
      }
      else {
        // If property does not match either of the above, return error message
        buf.append("Invalid request for type of total. Should be carbon or energy.");
      }
      
    }
    catch (ResourceNotFoundException rnfe) {
      // Occurs if source does not exist
      buf.append(resourceNotFoundMessage);
      buf.append(source);
    }
    catch (MiscClientException mce) {
      // Occurs if error happens while getting data
      buf.append(miscClientMessage);
    }
    catch (NotAuthorizedException nae) {
      // Occurs if user is not authorized to get information
      buf.append(notAuthorizedMessage);
    }
    catch (BadXmlException bxe) {
      // Occurs if data is corrupted
      buf.append(badXmlMessage);
    }
    catch (NumberFormatException nfe) {
      // Occurs if the user did not put a valid number for minutes
      buf.append(numberFormatMessage);
    }
    catch (Exception e) {
      // Catch any other errors
      buf.append("Encountered error: ");
      buf.append(e);
    }

    // Put output from buffer into output string and return
    out = buf.toString();
    return out;
  }
  

}
